package com.jiantong.web.open.app.lawEnforcing;

import com.google.common.collect.Maps;
import com.jiantong.lawEnforcing.dto.WritDataDto;
import com.jiantong.lawEnforcing.enums.RecordType;
import com.jiantong.lawEnforcing.model.Datas;
import com.jiantong.lawEnforcing.model.OriginField;
import com.jiantong.lawEnforcing.service.DatasService;
import com.jiantong.lawEnforcing.service.OriginFieldService;
import com.jiantong.web.core.enums.ExceptionCode;
import io.terminus.boot.rpc.common.annotation.RpcConsumer;
import io.terminus.common.model.Response;
import io.terminus.pampas.openplatform.annotations.OpenBean;
import io.terminus.pampas.openplatform.annotations.OpenMethod;
import io.terminus.pampas.openplatform.exceptions.OPClientException;
import io.terminus.pampas.openplatform.exceptions.OPServerException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 存储信息
 * Created by mz03 on 2017/8/15.
 */
@Slf4j
@OpenBean
public class DatasApis {

    @RpcConsumer
    private DatasService datasService;
    @RpcConsumer
    private OriginFieldService originFieldService;


    /**
     * 根据类型查找文书
     * @param law_case
     * @param origin_type_one
     * @return
     */
    @OpenMethod(
            key = "find.data.list.by.id",
            paramNames = {"law_case","origin_type_one"},
            httpMethods = RequestMethod.GET
    )
    public List<Datas> findDataList(Long law_case,Integer origin_type_one){
        Map<String,Object> map = Maps.newHashMap();
        if (law_case != null) {
            map.put("law_case",law_case);
        }
        if (origin_type_one != null) {
            map.put("origin_type_one", origin_type_one);
        }
        Response<List<Datas>> response = datasService.findDataList(map);
        if (!response.isSuccess()){
            log.error("查询文书类型下所有已制作的文书失败, cause : {}", response.getError());
            throw new OPServerException(response.getError());
        }
        //把字段名改为文书类型的文字说明
        for (Datas datas:response.getResult()) {
            RecordType recordType = RecordType.from(datas.getOrigin_type_two());
            if (recordType == null) {
                log.error("未找到对应的文书类型:",datas.getOrigin_type_two());
                throw new OPServerException("未找到对应的文书类型:"+datas.getOrigin_type_two());
            }
            datas.setOrigin_name(recordType.toString());
        }

        return response.getResult();
    }

    /**
     * 根据id查询一条信息
     * @param id
     * @return
     */
    @OpenMethod(
            key = "find.Datas.by.id",
            paramNames = {"id"},
            httpMethods = RequestMethod.GET
    )
    public Datas findById(Long id){
        Response<Datas> response = datasService.finById(id);
        if (!response.isSuccess()){
            log.error("failed to find Datas read by id = {}, cause : {}", id, response.getError());
            throw new OPServerException(response.getError());
        }
        return response.getResult();
    }



    /**
     * 查询一个文书
     * 根据 案件di和originIds 查找一组  可以用来查询指定案件的某种文书的所有数据
     * @param originType
     * @return
     */
    @OpenMethod(
            key = "find.data.list.by.originIds",
            paramNames = {"casesId","originType","count"},
            httpMethods = RequestMethod.GET
    )
    public WritDataDto findByOriginIds(Long casesId, Integer originType,Integer count){

        //查到指定文书的所有元数据
        OriginField originField = new OriginField();
        originField.setDetailed_type(originType);
        Response<List<OriginField>> listResponse = originFieldService.finByList(originField);
        List<OriginField> list = listResponse.getResult();
        //拿到元数据中指定文书的所有origin_id
        List<Long> originIds = new ArrayList<>();
        for (OriginField or : list) {
            originIds.add(or.getId());
        }

        Map<String,Object> map = Maps.newHashMap();
        if (casesId != null) {
            map.put("law_case", casesId);
        }
        if (count != null) {
            map.put("count", count);
        }
        if (originIds.size() != 0) {
            map.put("originIds",originIds);
        }
        Response<List<Datas>> response = datasService.findByOriginIds(map);
        if (!response.isSuccess()){
            log.error("failed to find DatasList read by originIds cause : {}", response.getError());
            throw new OPServerException(response.getError());
        }

        Map<String,Object> map1 = Maps.newHashMap();
        for (Datas data : response.getResult()) {
            map1.put(data.getOrigin_name(), data.getData());
        }

        WritDataDto writDataDto = new WritDataDto();
        writDataDto.setWrit_type(originType);
        writDataDto.setCases_id(casesId);
        writDataDto.setMap(map1);

        return writDataDto;
    }


    /**
     * 创建一条信息
     * @param goods
     * @return
     */
    @OpenMethod(
            key = "create.Datas",
            paramNames = {"Datas"},
            httpMethods = RequestMethod.POST
    )
    public Long create(Datas goods){
        Response<Long> response = datasService.create(goods);
        if(!response.isSuccess()){
            log.error("failed to create datas read by goods = {}, cause : {}", goods, response.getError());
            throw new OPServerException(response.getError());
        }
        return response.getResult();
    }
/*
     * @param cases_id  案件id
     * @param writ_type 文书二级类型 101:询问笔录类型
     * @param
 */

    /**
     * 创建一则文书
     * @param writDataDto: 由cases_id  案件id,writ_type 文书二级类型,dataMap 相应的文书类型的所有数据 <origin_name, date> 组成;
     * @return 创建成果的条数
     */
    @OpenMethod(
            key = "create.datas.list",
            paramNames = {"writDataDto"},
            httpMethods = RequestMethod.POST
    )
    public Integer creates(WritDataDto writDataDto){
        //根据文书类型拿到此类型下的所有origin
        Map<String,Object> map = writDataDto.getMap();
        Long cases_id = writDataDto.getCases_id();
        Integer writ_type = writDataDto.getWrit_type();

        OriginField originField = new OriginField();
        originField.setDetailed_type(writ_type);
        Response<List<OriginField>> response = originFieldService.finByList(originField);
        if (!response.isSuccess()){
            log.error("failed to find OriginField  by originField, cause : {}", response.getError());
            throw new OPServerException(response.getError());
        }
        List<OriginField> originList = response.getResult();

        //先查一下,这是第几次新建单据? 根据cases_id 和 writ_type 查询最大的count
        String origin_name = originList.get(0).getName();
        Response<Integer> integerResponse = datasService.findDatasCount(cases_id,origin_name);//案件id 和 文书类型 查出来目前有多少条了
        if (!integerResponse.isSuccess()) {
            log.error("查找文书创建次数失败, 原因 : {}", integerResponse.getError());
            throw new OPServerException(integerResponse.getError());
        }
        Integer count;
        if (integerResponse.getResult()==null){
            count = 1;
        }else {
            count = integerResponse.getResult() + 1;//此类型文书是第几次创建
        }
        List<Datas> datasList = new ArrayList<>();
        String origin_type_one = "";
        Integer type_one = null;
        if (writ_type!=null){
            String origin_type_two = writ_type.toString();
            origin_type_one = origin_type_two.substring(0,(origin_type_two.length()-2));
            type_one = new Integer(origin_type_one);
        }
        Object object;
        //根据传来的参数组成一组Data
        for (OriginField origin : originList) {
            Datas datas = new Datas();
            datas.setLaw_case(cases_id);
            datas.setOrigin_type_one(type_one);//一级类型
            datas.setOrigin_type_two(writ_type);//二级类型
            datas.setCount(count);
            datas.setOrigin_id(origin.getId());
            datas.setOrigin_name(origin.getName());
            object = map.get(origin.getName());
            if (object==null){
                datas.setData(null);
                datasList.add(datas);
            }else {
                datas.setData(object.toString());
                datasList.add(datas);
            }
        }
        Response<Integer> response1 = datasService.creates(datasList);//创建一组Data 返回创建的个数
        if(!response1.isSuccess()){
            log.error("failed to create datas read by datasList,  cause : {}", response.getError());
            throw new OPServerException(response.getError());
        }
        return response1.getResult();
    }

    /**
     * 更新单据  此更新基本上都是一下更新很多条, 并且是根据case_id和origin_id进行更新,而不是根据单据id.
     * 所以最好是放到事务里,先把需要更新的数据删除,然后根据拿着需要跟新的数据去重新创建.
     */
    @OpenMethod(
            key = "update.datas.list",
            paramNames = {"writDataDto"},
            httpMethods = RequestMethod.PUT
    )
    public Integer updates(WritDataDto writDataDto){

        Response<Integer> response = datasService.deletesByOriginIds(writDataDto);
        if (!response.isSuccess()) {
            log.error("failed.update.datas.list",response.getError());
            throw new OPServerException(response.getError());
        }
        return response.getResult();
    }

    /**
     * 更新数据
     * @param datas
     * @return
     */
    @OpenMethod(
            key = "update.ask.datas",
            paramNames = {"datas"},
            httpMethods = RequestMethod.PUT
    )
    public Boolean update(Datas datas){
        if(datas.getId() == null){
            log.error("id should be not null");
            throw new OPClientException(ExceptionCode.ID_NOT_EXIST.value(),
                    "id should be not null");
        }
        Response<Boolean> response = datasService.update(datas);
        if(!response.isSuccess()){
            log.error("failed to update datas");
            throw new OPServerException(ExceptionCode.DATA_UPDATE_FAIL.value(),
                    "failed to update datas");
        }
        return response.getResult();
    }

}
